package kite.sso.service.comp;

import kite.sso.config.KiteSsoConfig;
import kite.sso.exception.ExpType;
import kite.sso.exception.KiteAuthException;
import kite.sso.message.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Collection;

/**
 * 功能描述: <br>
 * 所属包名: kite.sso.service.custom<br>
 * 创建人　: 白剑<br>
 * 创建时间: 2018/06/04 23:19:21<br>
 * 当前版本: 1.0<br>
 * 修改历史: <br>
 * 修改时间　　　　　修改人　　　　　版本变更　　　　　修改说明<br>
 * -----------------------------------------------------<br>
 * <br>
 */
@Component
public class KiteLoginAuthProvider implements AuthenticationProvider {

    @Autowired
    private KiteUserDetailsService userDetailsService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String username = authentication.getName();
        String password = (String) authentication.getCredentials();

        UserEntity userEntity = (UserEntity) userDetailsService.loadUserByUsername(username);
        if (null == userEntity) {
            throw new KiteAuthException(ExpType.USER_NOT_FOUND);
        }
        if (!userEntity.isEnabled()) {
            throw new KiteAuthException(ExpType.USER_IS_DISABLED);
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(KiteSsoConfig.PASSWORD_STRENGTH);
        if (!encoder.matches(password, userEntity.getPassword())) {
            throw new KiteAuthException(ExpType.USER_PASSWORD_ERROR);
        }

        Collection<? extends GrantedAuthority> authorities = userEntity.getAuthorities();
        return new UsernamePasswordAuthenticationToken(userEntity, password, authorities);
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return UsernamePasswordAuthenticationToken.class.equals(aClass);
    }
}
